package org.boinc.screensaver;

import gov.nasa.worldwind.BasicModel;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.awt.WorldWindowGLCanvas;
import gov.nasa.worldwind.geom.Angle;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.layers.RenderableLayer;
import gov.nasa.worldwind.render.Offset;
import gov.nasa.worldwind.render.ScreenImage;
import gov.nasa.worldwind.render.Size;
import gov.nasa.worldwind.view.firstperson.BasicFlyView;
import gov.nasa.worldwind.view.firstperson.FlyToFlyViewAnimator;

import java.awt.Frame;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import javax.imageio.ImageIO;

///
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.data.general.DefaultPieDataset;

import java.awt.image.BufferedImage;

public class FullScreenTest {

	public static double test = 0;

	/**
	 * The animated view
	 */
	public static BasicFlyView view;
	public static WorldWindowGLCanvas worldWindowGLCanvas;
	public static List<ScreenImage> chartsImages;

	/**
	 * The ScreenSaver entry point, should run in windowed mode with
	 * interactivity or fullscreen mode depending on flags
	 * http://boinc.berkeley.edu/trac/wiki/ScreensaverEnhancements
	 * 
	 * @param args
	 */
	public static void main(String[] args) {

		view = new BasicFlyView();
		Frame frame = new Frame("WorldwindFull");
		// final WorldWindowGLCanvas worldWindowGLCanvas = new
		// WorldWindowGLCanvas();
		worldWindowGLCanvas = new WorldWindowGLCanvas();
		worldWindowGLCanvas.setModel(new BasicModel());
		worldWindowGLCanvas.setView(view);

		worldWindowGLCanvas.addKeyListener(new java.awt.event.KeyListener() {
			public void keyTyped(KeyEvent e) {
			}

			public void keyReleased(KeyEvent e) {
			}

			public void keyPressed(KeyEvent e) {
				if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
					System.exit(0);
				}
			}
		});

		RenderableLayer creditsLayer = new RenderableLayer();
		creditsLayer.setName("Credits");
		try {
			creditsLayer.addRenderables(createCredits());
		} catch (IOException ioEx) {

			ioEx.printStackTrace();
		}
		worldWindowGLCanvas.getModel().getLayers().add(creditsLayer);

		// //
		RenderableLayer chartsLayer = new RenderableLayer();
		chartsLayer.setName("Charts");
		try {
			chartsImages = createCharts();
			chartsLayer.addRenderables(chartsImages);
		} catch (IOException ioEx) {

			ioEx.printStackTrace();
		}
		worldWindowGLCanvas.getModel().getLayers().add(chartsLayer);

		frame.add(worldWindowGLCanvas);
		frame.setSize(640, 480);
		frame.setUndecorated(true);
		int size = frame.getExtendedState();
		size |= Frame.MAXIMIZED_BOTH;
		frame.setExtendedState(size);

		frame.setVisible(true);
		worldWindowGLCanvas.requestFocus();

		setUpTimer();
	}

	/**
	 * Static method to produce credits for all involved organisations
	 * 
	 * @return
	 * @throws IOException
	 */
	public static List<ScreenImage> createCredits() throws IOException {
		List<ScreenImage> allCredits = new ArrayList<ScreenImage>();
		ScreenImage creditWWC = new ScreenImage();
		creditWWC.setImageSource(ImageIO.read(new File(
				"src/images/worldwindcentral.gif")));
		// TODO: More flexible out of code layout policy
		creditWWC.setScreenOffset(new Offset(0.10, 0.90, AVKey.FRACTION,
				AVKey.FRACTION));
		creditWWC.setSize(new Size(Size.MAINTAIN_ASPECT_RATIO, 0.05,
				AVKey.FRACTION, Size.MAINTAIN_ASPECT_RATIO, 0.05,
				AVKey.FRACTION));

		ScreenImage creditRKN = new ScreenImage();
		creditRKN.setImageSource(ImageIO.read(new File(
				"src/images/logo_selfnet1.png")));
		// TODO: More flexible out of code layout policy
		creditRKN.setScreenOffset(new Offset(0.50, 0.90, AVKey.FRACTION,
				AVKey.FRACTION));
		creditRKN.setSize(new Size(Size.MAINTAIN_ASPECT_RATIO, 0.05,
				AVKey.FRACTION, Size.MAINTAIN_ASPECT_RATIO, 0.05,
				AVKey.FRACTION));

		allCredits.add(creditWWC);
		allCredits.add(creditRKN);
		return allCredits;
	}

	public static List<ScreenImage> createCharts() throws IOException {

		final BufferedImage image = getChartImage();

		List<ScreenImage> allCharts = new ArrayList<ScreenImage>();
		ScreenImage chart1 = new ScreenImage();
		chart1.setImageSource(image);
		// TODO: More flexible out of code layout policy
		chart1.setScreenOffset(new Offset(0.10, 0.60, AVKey.FRACTION,
				AVKey.FRACTION));
		chart1.setSize(new Size(Size.MAINTAIN_ASPECT_RATIO, 0.05,
				AVKey.FRACTION, Size.MAINTAIN_ASPECT_RATIO, 0.05,
				AVKey.FRACTION));

		allCharts.add(chart1);
		return allCharts;
	}

	private static BufferedImage getChartImage() {
		// create a dataset...
		DefaultPieDataset dataset = new DefaultPieDataset();
		dataset.setValue("Category 1", 43.2 - test);
		dataset.setValue("Category 2", 27.9 + test);
		dataset.setValue("Category 3", 79.5);
		// create a chart...
		JFreeChart chart = ChartFactory.createPieChart("Sample Pie Chart",
				dataset, true, // legend?
				true, // tooltips?
				false // URLs?
				);

		final BufferedImage image = chart.createBufferedImage(300, 200);
		return image;
	}

	/**
	 * The globe auto-rotate animator
	 * 
	 * @param pos
	 */
	public static void moveToLocation(Position pos) {
		if (pos == null) {
			return;
		}
		double elevation = view.getGlobe().getElevation(pos.getLatitude(),
				pos.getLongitude());
		FlyToFlyViewAnimator animator = FlyToFlyViewAnimator
				.createFlyToFlyViewAnimator(view, view.getEyePosition(),
						new Position(pos.latitude, pos.longitude, elevation),
						view.getHeading(), view.getHeading(), view.getPitch(),
						view.getPitch(), view.getEyePosition().getElevation(),
						view.getEyePosition().getElevation(), 10000, 0);
		view.addAnimator(animator);
		animator.start();
		view.firePropertyChange(AVKey.VIEW, null, view);
	}

	/**
	 * Convenience timer set-up to periodically rotate the globe
	 */
	public static void setUpTimer() {
		int delay = 5000; // delay for 5 sec.
		int period = 10000; // repeat every sec.
		Timer timer = new Timer();

		timer.scheduleAtFixedRate(new TimerTask() {
			public void run() {
				Position pos = new Position(
						Angle
								.fromDegrees(180 * new Random().nextFloat() - 90.0),
						Angle
								.fromDegrees(360 * new Random().nextFloat() - 180.0),
						0.0);
				moveToLocation(pos);

				Random rn = new Random();
				int n = 20 - 0 + 1;
				int i = rn.nextInt() % n;
				FullScreenTest.test = 0 + i;
				System.out.println(FullScreenTest.test);

				BufferedImage image = getChartImage();
				chartsImages.get(0).setImageSource(image);
				worldWindowGLCanvas.redraw();

			}
		}, delay, period);
	}
}
